package es.unileon.rnag.jgen.genes;

import java.util.List;

/**
 * Clase que representa un gen que puede tomar valores dentro de una lista de posibles valores
 * @author Abel Mayorga Gonz&aacute;lez
 * @author Sergio Fern&aacute;ndez Mart&iacute;nez
 * @version 1.0
 * @param <T> Tipo de datos de la lista de posibles valores
 */
public class GenLista<T> implements Gen<T> {
	
	private List<T> _listaValores;
	private int _valor;
	
	/**
	 * Constructor. Obtiene un valor aleatorio de la lista
	 * @param lista: Lista de posibles valores
	 */
	public GenLista(List<T> lista){
		_listaValores = lista;
		_valor = (int)Math.floor(Math.random()*lista.size());
	}
	
	@Override
	public T getValor() {
		return _listaValores.get(_valor);
	}

	@Override
	public boolean esValido(T valor) {
		return _listaValores.contains(valor);
	}

	@Override
	public String getBitString() {
		String bitString = Integer.toBinaryString(_valor);
		int bits = (int)Math.ceil(Math.log(_listaValores.size())/Math.log(2));
		while(bits>bitString.length()){
			bitString="0".concat(bitString);
		}
		return bitString;
	}

	@Override
	public boolean asignarValor(String bits) {
		int nuevo = Integer.parseInt(bits,2);
		if((0<=nuevo) && (nuevo < _listaValores.size())){
			_valor = nuevo;
			return true;
		} else {
			return false;
		}
	}

	@Override
	public boolean asignarValor(T valor) {
		if(esValido(valor)){
			this._valor=_listaValores.indexOf(valor);
			return true;
		} else {
			return false;
		}
	}

	@Override
	public Gen<T> clonar() {
		GenLista<T> nuevo = new GenLista(_listaValores);
		nuevo.asignarValor(_listaValores.get(_valor));
		return nuevo;
	}

}
